package sdk;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class CommonSDK {

    public static String generateSignature(Map<String, Object> params, String appSecret) {
        Map<String, Object> filteredParams = new TreeMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            if (!entry.getKey().equals("sign")) {
                Object value = entry.getValue();
                // if (value instanceof List) {
                //     // 如果是List类型，遍历并拼接元素
                //     List<?> list = (List<?>) value;
                //     StringBuilder sb = new StringBuilder("[");
                //     for (int i = 0; i < list.size(); i++) {
                //         sb.append(list.get(i).toString());
                //         if (i < list.size() - 1) {
                //             sb.append(", ");
                //         }
                //     }
                //     sb.append("]");
                //     filteredParams.put(entry.getKey(), sb.toString());
                // } else {
                //     // 否则直接放入
                    filteredParams.put(entry.getKey(), value);
                // }
            }
        }

        StringBuilder strToSign = new StringBuilder();
        for (Map.Entry<String, Object> entry : filteredParams.entrySet()) {
            strToSign.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        strToSign.deleteCharAt(strToSign.length() - 1);

        try {
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKey = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            hmacSha256.init(secretKey);
            byte[] hash = hmacSha256.doFinal(strToSign.toString().getBytes(StandardCharsets.UTF_8));
            StringBuilder signature = new StringBuilder();
            for (byte b : hash) {
                signature.append(String.format("%02x", b));
            }
            return signature.toString();
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to generate signature", e);
        }
    }

    public static Map<String, Object> extractParams(String method, Map<String, Object> queryParams, Map<String, Object> bodyParams) {
        Map<String, Object> params = new TreeMap<>();
        for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
            if (entry.getValue() != null && !entry.getValue().toString().trim().isEmpty()) {
                params.put(entry.getKey(), entry.getValue());
            }
        }
    
        if (method.equals("POST") || method.equals("PUT") || method.equals("PATCH") || method.equals("DELETE")) {
            if (bodyParams != null) {
                for (Map.Entry<String, Object> entry : bodyParams.entrySet()) {
                    if (entry.getValue() instanceof Iterable) {
                        // Iterable<?> iterable = (Iterable<?>) entry.getValue();
                        // StringBuilder sb = new StringBuilder();
                        // for (Object item : iterable) {
                        //     if (item != null) {
                        //         sb.append(item.toString()).append(",");
                        //     }
                        // }
                        // if (sb.length() > 0) {
                        //     sb.setLength(sb.length() - 1);
                        // }
                        // params.put(entry.getKey(), sb.toString());
                        params.put(entry.getKey(), entry.getValue());
                    } else {
                        // 非 Iterable 类型直接转为字符串
                        if (entry.getValue().toString() !="") {
                            params.put(entry.getKey(), entry.getValue().toString());
                        }
                    }
                }
            } else {
                throw new IllegalArgumentException("Unsupported request body format");
            }
        }
        return params;
    }

}



    
class BuildClientSDK {
    private String appId;
    private String appSecret;

    public BuildClientSDK(String appId, String appSecret) {
        this.appId = appId;
        this.appSecret = appSecret;
    }

    public  Map<String, Object> buildGetParam(Map<String, Object> params) {
        params.put("app_id", appId);
        params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        params.put("sign", CommonSDK.generateSignature(CommonSDK.extractParams("GET", params, params), appSecret));
        return params;
    }

    public Map<String, Object> buildPostParam(Map<String, Object> params) {
        params.put("app_id", appId);
        params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        params.put("sign", CommonSDK.generateSignature(CommonSDK.extractParams("POST", new TreeMap<>(), params), appSecret));
        return params;
    }
}